﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Practices.ESB.Resolver;
using Microsoft.Practices.ESB.Resolver.BRE;
using Microsoft.Practices.ESB.Exception.Management;
using Microsoft.XLANGs.BaseTypes;
using System.Reflection;
using BizTalk.ESB.Extensions.Helpers;

namespace BizTalk.ESB.Extensions.Resolvers
{
    public class PropertyPromoterResolution
    {
        public string PropertyPromotionConfig { get; set; }
        public string DocumentSpecStrongName { get; set; }

        public void SetPropertySource(string BamFieldName, string ValueOrMappingToUse)
        {
            if (!string.IsNullOrEmpty(BamFieldName) && !string.IsNullOrEmpty(ValueOrMappingToUse))
            {
                var sb = new StringBuilder();
                if (!string.IsNullOrEmpty(this.PropertyPromotionConfig))
                {
                    sb.Append(this.PropertyPromotionConfig);
                    sb.Append(@"&");
                }
                sb.Append(BamFieldName);
                sb.Append(@"=");
                sb.Append(ValueOrMappingToUse);
                this.PropertyPromotionConfig = sb.ToString();
            }
        }
    }

    public class PropertyPromoterResolutionManager
    {
        //public static BRE CreateResolverDescriptor(string config, string resolver)
        //{
        //    BRE breWrapper;

        //    if (config == null)
        //    {
        //        throw new ArgumentNullException("config");
        //    }
        //    if (resolver == null)
        //    {
        //        throw new ArgumentNullException("resolver");
        //    }

        //    Dictionary<String, String> facts = null;
        //    try
        //    {
        //        BRE breTemp = new BRE();
        //        breTemp.useMsg = false;
        //        facts = ResolverMgr.GetFacts(config, resolver);
        //        breTemp.policy = ResolverMgr.GetConfigValue(facts, true, "policy");
        //        breTemp.version = ResolverMgr.GetConfigValue(facts, false, "version");
        //        Boolean useMessage, recognizeMessage;
        //        breTemp.useMsgSpecified = Boolean.TryParse(
        //            ResolverMgr.GetConfigValue(facts, false, "useMsg")
        //            , out useMessage);
        //        breTemp.recognizeMessageFormatSpecified = Boolean.TryParse(
        //            ResolverMgr.GetConfigValue(facts, false, "recognizeMessageFormat")
        //            , out recognizeMessage);
        //        breTemp.useMsg = useMessage;
        //        breTemp.recognizeMessageFormat = recognizeMessage;

        //        breWrapper = breTemp;
        //    }
        //    catch (Exception e)
        //    {
        //        EventLogger.Write(MethodBase.GetCurrentMethod(), e);
        //        throw;
        //    }
        //    finally
        //    {
        //        if (facts != null)
        //        {
        //            facts.Clear();
        //            facts = null;
        //        }
        //    }

        //    return breWrapper;
        //}

        public static void SetResolverDictionary(PropertyPromoterResolution resolution, Dictionary<String, String> dictionary)
        {
            try
            {
                dictionary.Add("Resolver.PropertyPromotionConfig", resolution.PropertyPromotionConfig);
            }
            catch { }
        }

        public static void SetContext(BamTrackingResolution resolution, XLANGMessage message)
        {
            if (message == null)
            {
                throw new ArgumentNullException("message");
            }
            if (resolution == null)
            {
                throw new ArgumentNullException("resolution");
            }
            try
            {
                resolution.DocumentSpecStrongName = ((string)PropertyPromoterResolutionManager.GetMsgProperty(message
                    , typeof(BTS.SchemaStrongName))) ?? String.Empty;
                if (String.IsNullOrEmpty(resolution.DocumentSpecStrongName) == false)
                {
                    int index = resolution.DocumentSpecStrongName.IndexOf(",", StringComparison.CurrentCultureIgnoreCase);
                    if ((index > 0) && (index < resolution.DocumentSpecStrongName.Length))
                    {
                        resolution.DocumentSpecStrongName = resolution.DocumentSpecStrongName.Substring(0, index);
                    }
                }
            }
            catch (Exception e)
            {
                EventLogger.Write(MethodBase.GetCurrentMethod(), e);
                throw;
            }
        }

        private static Object GetMsgProperty(XLANGMessage message, Type property)
        {
            Object prop;
            if (message == null)
            {
                throw new ArgumentNullException("message");
            }
            if (property == null)
            {
                throw new ArgumentNullException("property");
            }
            Object PropertyValue = null;
            try
            {
                PropertyValue = message.GetPropertyValue(property);
                prop = PropertyValue;
            }
            catch (Exception e)
            {
                EventLogger.Write(MethodBase.GetCurrentMethod(), e);
                throw;
            }
            finally
            {
                if (PropertyValue != null)
                {
                    PropertyValue = null;
                }
            }
            return prop;
        }
    }
}
